package com.dhecp.project.logstics.service.impl;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.IpUtils;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.core.constant.DataFiltering;
import com.dhecp.core.utils.PageUtils;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.business.domain.FbaShipmentDetail;
import com.dhecp.project.common.service.UpdateLogService;
import com.dhecp.project.common.service.impl.BaseModuleServiceImpl;
import com.dhecp.project.finance.domain.AccountCountForCompany;
import com.dhecp.project.finance.domain.AccountDetailedForCompany;
import com.dhecp.project.finance.mapper.AccountCountForCompanyMapper;
import com.dhecp.project.finance.mapper.AccountDetailedForCompanyMapper;
import com.dhecp.project.hr.domain.OperateCompanyApply;
import com.dhecp.project.hr.mapper.OperateCompanyApplyMapper;
import com.dhecp.project.logstics.domain.FbaDevanning;
import com.dhecp.project.logstics.domain.FbaDevanningDetail;
import com.dhecp.project.logstics.mapper.FbaDevanningDetailMapper;
import com.dhecp.project.logstics.mapper.FbaDevanningMapper;
import com.dhecp.project.logstics.service.FbaDevanningService;
import com.dhecp.project.storage.domain.StockControl;
import com.dhecp.project.storage.domain.StockControlRunning;
import com.dhecp.project.storage.mapper.StockControlMapper;
import com.dhecp.project.storage.mapper.StockControlRunningMapper;
import com.dhecp.project.system.domain.SysAccountBandDept;
import com.dhecp.project.system.mapper.SysAccountBandDeptMapper;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;

/**
 * 头程装箱单 服务层
 * @Author fxz
 * @Date 2022/9/23
 */
@Service
public class FbaDevanningServicelmpl extends BaseModuleServiceImpl implements FbaDevanningService {

    @Autowired
    private FbaDevanningMapper fbaDevanningMapper;
    @Autowired
    private FbaDevanningDetailMapper fbaDevanningDetailMapper;

    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;

    @Autowired
    private StockControlMapper storageMapper;

    @Autowired
    private UpdateLogService updateLogService;

    @Autowired
    private OperateCompanyApplyMapper businessMapper;

    @Autowired
    private StockControlRunningMapper stockControlRunningMapper;

    @Autowired
    private AccountCountForCompanyMapper accountCountForCompanyMapper;

    @Autowired
    private SysAccountBandDeptMapper sysAccountBandDeptMapper;

    @Autowired
    private AccountDetailedForCompanyMapper accountDetailedForCompanyMapper;





    /**
     * 头程装箱单列表
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<FbaDevanning> queryList(Map<String, Object> params) throws Exception {
        //特殊字段商品编码修改查询详情有关联的数据
        if (params.get("CommodityCode") != null && !params.get("CommodityCode").equals("")){
            params.put("commodityCode1",params.get("CommodityCode"));
            params.put("CommodityCode","");
        }
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句

        if (params.get("field") == null || params.get("field") == ""){
            String orderBy = "createTime DESC";
            PageUtils.startPageOrder(orderBy);
        }else{
            PageUtils.startPage();
        }

        return fbaDevanningMapper.select(params);
    }

    /**
     * 查询头程拆箱详情单
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<FbaDevanningDetail> querySonList(Map<String, Object> params) throws Exception {
        return fbaDevanningDetailMapper.queryList(params);
    }

    @Override
    public FbaDevanning queryFirstRecord(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        return fbaDevanningMapper.selectFirstRecordByNid(params);
    }

    /**
     *@Description: 保存
     *@Param: [params] moduleTable 必要参数：功能唯一标识
     *@Param: [params] infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     *@Param: [params] infoItems 必要参数：对应实体类的json格式字符串
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: hlf
     *@date: 2022-05-09 10:10
     */
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult saveData(Map<String, Object> params) {
        if (params.get("infoMap") == null || params.get("infoMap") == "") {
            return AjaxResult.error(MessageUtils.message("module.error.lack.infomap"));
        }
        FbaDevanning fbaDevanning = JSON.parseObject(params.get("infoMap").toString(), FbaDevanning.class);
        fbaDevanning.setUpdateTime(new Date());
        if (fbaDevanning.getStateNameCx().equals("0")){
            fbaDevanning.setStateNameCxName("否");
        }else {
            fbaDevanning.setStateNameCxName("是");

        }
        if (fbaDevanning.getStateNameZx().equals("0")){
            fbaDevanning.setStateNameZxName("否");
        }else {
            fbaDevanning.setStateNameZxName("是");

        }
        //修改拆箱信息
        fbaDevanningMapper.update(fbaDevanning);

        //删除对应的拆箱详情数据
        fbaDevanningDetailMapper.delete(fbaDevanning.getCodeDevanning());
        //返回id用于前端查询
        String resGuid = fbaDevanning.getGuid();
        //新增拆箱详情数据
        List<FbaDevanningDetail> fbaDevanningDetailList = JSON.parseArray(params.get("infoItems").toString(), FbaDevanningDetail.class);
        for (FbaDevanningDetail fbaDevanningDetail : fbaDevanningDetailList){
            fbaDevanningDetail.setCodeDevanning(fbaDevanning.getCodeDevanning());
        }
        fbaDevanningDetailMapper.batchInsert(fbaDevanningDetailList);
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"),resGuid);

    }

    /**
     * 修改审核状态
     * @return
     * @author DH-Xxj
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateState(Map<String, Object> params) {
        List<FbaDevanning> fbaDevanningList =  JSON.parseArray(params.get("infoItems").toString(), FbaDevanning.class);
        Map<String, Object> params1 = new HashMap<String, Object>();
        List<FbaDevanningDetail> fbaDevanningDetailList;
        for (FbaDevanning item:fbaDevanningList
        ) {
            params1.put("guid",item.getGuid());
            FbaDevanning fbaDevanning = fbaDevanningMapper.selectFirstRecordByNid(params1);
            if (fbaDevanning == null){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("拆箱单信息不存在!");
            }
            if (fbaDevanning.getState().equals("1")){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("拆箱单信息已审核,不允许审核!");
            }
            fbaDevanning.setUpdateTime(new Date());
            fbaDevanning.setState(params.get("state").toString());
            fbaDevanning.setAuditTime(new Date());
            fbaDevanning.setAuditUser(ShiroUtils.getUserId());
            fbaDevanningMapper.update(fbaDevanning);

            AccountCountForCompany operationAccount = null;
            AccountCountForCompany warehousingAccount = null;
            SysAccountBandDept sysAccountBandDept;
            List<AccountDetailedForCompany> accountList = new ArrayList<>();
            if (fbaDevanning.getStateNameCxName().equals("是") || fbaDevanning.getStateNameZxName().equals("是")) {
                operationAccount = accountCountForCompanyMapper.queryFirstByVGsBm(fbaDevanning.getCodeCompany());
                if (operationAccount == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error("运营公司实时资金不存在,请核实后再操作!");
                }

                //查询仓储部绑定账户
                sysAccountBandDept = sysAccountBandDeptMapper.findByAccountId("CCB");
                if (sysAccountBandDept == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error("仓储部绑定账户未启用或不存在,请核实后再操作!");
                }
                // 仓储部绑定账户增加物流费用
                warehousingAccount = accountCountForCompanyMapper.queryFirstByVGsBm(sysAccountBandDept.getvGsBm());
                if (warehousingAccount == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error("仓储部实时资金不存在,请核实后再操作!");
                }
            }
            if (fbaDevanning.getStateNameCxName().equals("是")) {
                //拆箱费 一箱30
                Double boxProject = Double.valueOf(fbaDevanning.getNumBox()) * 30;
                //资金流水(运营公司-仓储部 拆箱费)
                AccountDetailedForCompany account = new AccountDetailedForCompany();
                account.setGuid(RandomValueUtils.getGUID());
                account.setvGsBm(operationAccount.getvGsBm());
                account.setvGsMc(operationAccount.getvGsMc());
                account.setvGsJc(operationAccount.getvGsJc());
                account.setvGsBmP(warehousingAccount.getvGsBm());
                account.setvGsMcP(warehousingAccount.getvGsMc());
                account.setvGsJcP(warehousingAccount.getvGsJc());
                account.setvJyLx("仓储服务→手续费");
                account.setfJe(-boxProject);
                account.setdJySj(fbaDevanning.getCreateTime());
                account.setdShSj(new Date());
                account.setvBz("拆箱费，头程计划单:" + fbaDevanning.getCodePlanOrder() + "," + "拆箱" + fbaDevanning.getNumBox() + "箱" + "," + "装箱单" + fbaDevanning.getCodeBox()+ ",头程拆箱单:" +fbaDevanning.getCodeDevanning());
                account.setCreateTime(new Date());
                accountList.add(account);

                //资金流水(仓储部-运营公司 拆箱费)
                AccountDetailedForCompany account1 = new AccountDetailedForCompany();
                account1.setGuid(RandomValueUtils.getGUID());
                account1.setvGsBm(warehousingAccount.getvGsBm());
                account1.setvGsMc(warehousingAccount.getvGsMc());
                account1.setvGsJc(warehousingAccount.getvGsJc());
                account1.setvGsBmP(operationAccount.getvGsBm());
                account1.setvGsMcP(operationAccount.getvGsMc());
                account1.setvGsJcP(operationAccount.getvGsJc());
                account1.setvJyLx("仓储服务→手续费");
                account1.setfJe(boxProject);
                account1.setdJySj(fbaDevanning.getCreateTime());
                account1.setdShSj(new Date());
                account1.setvBz("拆箱费，头程计划单:" + fbaDevanning.getCodePlanOrder() + "," + "拆箱" + fbaDevanning.getNumBox() + "箱" + "," + "装箱单" + fbaDevanning.getCodeBox()+ ",头程拆箱单:" +fbaDevanning.getCodeDevanning());
                account1.setCreateTime(new Date());
                accountList.add(account1);
            }

            //收取纸箱费
            if (fbaDevanning.getStateNameZxName().equals("是")) {
                //纸箱费 15元/箱
                Double boxProject = Double.valueOf(fbaDevanning.getNumBox()) * 15;
                //资金流水(运营公司-仓储部 拆箱费)
                AccountDetailedForCompany account = new AccountDetailedForCompany();
                account.setGuid(RandomValueUtils.getGUID());
                account.setvGsBm(operationAccount.getvGsBm());
                account.setvGsMc(operationAccount.getvGsMc());
                account.setvGsJc(operationAccount.getvGsJc());
                account.setvGsBmP(warehousingAccount.getvGsBm());
                account.setvGsMcP(warehousingAccount.getvGsMc());
                account.setvGsJcP(warehousingAccount.getvGsJc());
                account.setvJyLx("仓储服务→纸箱费");
                account.setfJe(-boxProject);
                account.setdJySj(fbaDevanning.getCreateTime());
                account.setdShSj(new Date());
                account.setvBz("拆箱纸箱费，头程计划单:" + fbaDevanning.getCodePlanOrder() + "," + "拆箱" + fbaDevanning.getNumBox() + "箱" + "," + "装箱单" + fbaDevanning.getCodeBox()+ ",头程拆箱单:" +fbaDevanning.getCodeDevanning());
                account.setCreateTime(new Date());
                accountList.add(account);

                //资金流水(仓储部-运营公司 拆箱费)
                AccountDetailedForCompany account1 = new AccountDetailedForCompany();
                account1.setGuid(RandomValueUtils.getGUID());
                account1.setvGsBm(warehousingAccount.getvGsBm());
                account1.setvGsMc(warehousingAccount.getvGsMc());
                account1.setvGsJc(warehousingAccount.getvGsJc());
                account1.setvGsBmP(operationAccount.getvGsBm());
                account1.setvGsMcP(operationAccount.getvGsMc());
                account1.setvGsJcP(operationAccount.getvGsJc());
                account1.setvJyLx("仓储服务→纸箱费");
                account1.setfJe(boxProject);
                account1.setdJySj(fbaDevanning.getCreateTime());
                account1.setdShSj(new Date());
                account1.setvBz("拆箱纸箱费，头程计划单:" + fbaDevanning.getCodePlanOrder() + "," + "拆箱" + fbaDevanning.getNumBox() + "箱" + "," + "装箱单" + fbaDevanning.getCodeBox()+ ",头程拆箱单:" +fbaDevanning.getCodeDevanning());
                account1.setCreateTime(new Date());
                accountList.add(account1);
            }

            if (accountList.size() != 0){
                accountDetailedForCompanyMapper.insertBatchNew(accountList);
            }
            //查询拆箱单详情信息
            params1.put("code",item.getCodeDevanning());
            fbaDevanningDetailList = fbaDevanningDetailMapper.queryFbaDevanningDetailList(params1);
            for (FbaDevanningDetail fbaDevanningDetail : fbaDevanningDetailList){
                if (fbaDevanningDetail.getNumStorage() == 0){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new RuntimeException("该拆箱单未处理上架数量,请核实后再操作!");
                }
                //回填库存数量
                updateNum(params,fbaDevanningDetail,fbaDevanning);
            }
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    private void updateNum( Map<String,Object> params,FbaDevanningDetail item,FbaDevanning fbaDevanning){
        StockControl oldData ;
        StockControl stockControl = new StockControl();
        String operatorName = "";
        if (item.getGuidKc() != null && !item.getGuidKc().equals("")){
            Map<String, Object> params2 = new HashMap<String, Object>();
            params2.put("rkGuid",item.getRkGuid());
            params2.put("vGsBm",item.getvGsBm());
            params2.put("vHw",item.getCodeStockLocation());
            params2.put("vKq",item.getCodeStockArea());
            params2.put("gDepot",item.getCodeStockOn());
            params2.put("productcode",item.getCommodityCode());
            oldData = storageMapper.findByMultiparameter(params2);
            if (oldData != null) {
                BeanUtils.copyProperties(oldData, stockControl);
                operatorName = "拆箱回填可用数量";
                //可用数量+计划发货
                stockControl.setProductNum(oldData.getProductNum() + item.getNumStorage());
                storageMapper.update(stockControl);
                addStockControl( stockControl, item, fbaDevanning, 1);
                updateLogService.addUpdateLog(params.get("moduleTable").toString(), stockControl.getGuid(), oldData, stockControl, operatorName);
            } else {
                Map<String, Object> params3 = new HashMap<String, Object>();
                params3.put("guid",item.getGuidKc());
                oldData = storageMapper.findById(params3);
                if (oldData != null){
                    BeanUtils.copyProperties(oldData, stockControl);
                    operatorName = "拆箱应更换货位扣减原库存总数量的计划数量";
                    //总数量-计划发货
                    stockControl.setProductNumAll(oldData.getProductNumAll() - item.getNumStorage());
                    storageMapper.update(stockControl);
                    addStockControl( stockControl, item, fbaDevanning, 2);
                    updateLogService.addUpdateLog(params.get("moduleTable").toString(), stockControl.getGuid(), oldData, stockControl, operatorName);
                }
                operatorName = "拆箱新增库存数量";
                //查询运营公司信息
                OperateCompanyApply vGsBm = businessMapper.findVGsBm(fbaDevanning.getCodeCompany());
                if (vGsBm == null){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    AjaxResult.error("运营公司不存在,请核实后在操作!");
                }
                stockControl.setGuid(RandomValueUtils.getGUID());
                stockControl.setRkGuid(item.getGuid());
//                stockControl.setRkBid(item.getCodeDevanning());
                stockControl.setCid(fbaDevanning.getCid());
                stockControl.setvHw(item.getCodeStockLocation());
                stockControl.setvKq(item.getCodeStockArea());
                stockControl.setgDepot(item.getCodeStockOn());
                stockControl.setProductName(item.getNameGoodsCn());
                stockControl.setProductCode(item.getCommodityCode());
                stockControl.setProductNum(item.getNumStorage());
                stockControl.setProductNumAll(item.getNumStorage());
                stockControl.setPurchasePrice(item.getPriceIn());
                stockControl.setPurchaseTotalPriceAll(item.getPriceIn() * item.getNumStorage());
                stockControl.setAllotPrice(item.getPriceIn());
                stockControl.setTotalAllotPrice(item.getPriceIn() * item.getNumStorage());
                stockControl.setsDays(0);
                stockControl.setAssembleID("");
                stockControl.setPurchaseStorageID("");
                stockControl.setPurchaseOrderID("");
                stockControl.setPurchasePlanID("");
                stockControl.setvGsMc(vGsBm.getvGsMc());
                stockControl.setvGsJc(vGsBm.getvGsJc());
                stockControl.setvGsBm(vGsBm.getvGsBm());
                stockControl.setdRkSj(new Date());
                stockControl.setCreateTime(new Date());
                stockControl.setIsParent("1");
                storageMapper.insert(stockControl);
                addStockControl( stockControl, item, fbaDevanning, 3);
                updateLogService.addUpdateLog(params.get("moduleTable").toString(), stockControl.getGuid(), oldData, stockControl, operatorName);
            }
        }
    }


    /**
     * 新增库存记录
     */
    private void addStockControl(StockControl stockControl,FbaDevanningDetail item,FbaDevanning fbaDevanning,Integer tpye){
        // 新库存添加库存流水
        StockControlRunning stockControlRunning = new StockControlRunning();
        stockControlRunning.setGuid(RandomValueUtils.getGUID());
        stockControlRunning.setGuidStockControl(stockControl.getGuid());
        stockControlRunning.setBidRelative(fbaDevanning.getBid());
        stockControlRunning.setLocationHw(item.getCodeStockLocation());
        stockControlRunning.setProductCode(item.getCommodityCode());
        stockControlRunning.setvGsBm(item.getvGsBm());
        stockControlRunning.setCreateTime(new Date());
        if (tpye == 1) {
            stockControlRunning.setProductNumChange(item.getNumStorage());
            stockControlRunning.setProductNumLeft(stockControl.getProductNumAll());
            stockControlRunning.setRemark("审核拆箱单 - 调入方 " + fbaDevanning.getCodeDevanning());
        } else  if (tpye == 2) {
            stockControlRunning.setProductNumChange(-item.getNumStorage());
            stockControlRunning.setProductNumLeft(stockControl.getProductNumAll());
            stockControlRunning.setRemark("拆箱应更换货位扣减原库存总数量的计划数量 " + fbaDevanning.getCodeDevanning());
        }else  if (tpye == 3) {
            stockControlRunning.setProductNumChange(item.getNumStorage());
            stockControlRunning.setProductNumLeft(stockControl.getProductNumAll());
            stockControlRunning.setRemark("拆箱新增库存数量 " + fbaDevanning.getCodeDevanning());
        }

        stockControlRunningMapper.insert(stockControlRunning);
    }

    /**
     *
     * @param logisticsAccount 转入公司账号
     * @param operationAccount 转出公司账号
     */
    private void addAccountDetailedForCompany(
            AccountCountForCompany logisticsAccount, AccountCountForCompany operationAccount,
            Double priceTranPredict,String vBz,String vJyLx
            ,String mname,int mType,String mNid,String mBid,String mGuid,Date dJySj,List<AccountDetailedForCompany> accountList){
        AccountDetailedForCompany account = new AccountDetailedForCompany();
        account.setGuid(RandomValueUtils.getGUID());
        account.setvGsBm(operationAccount.getvGsBm());
        account.setvGsMc(operationAccount.getvGsMc());
        account.setvGsJc(operationAccount.getvGsJc());
        account.setvGsBmP(logisticsAccount.getvGsBm());
        account.setvGsMcP(logisticsAccount.getvGsMc());
        account.setvGsJcP(logisticsAccount.getvGsJc());
        account.setvJyLx(vJyLx);
        account.setfJe(priceTranPredict);
        account.setdJySj(dJySj);
        account.setdShSj(new Date());
        account.setvBz(vBz);
        account.setCreateTime(new Date());
        account.setmName(mname);
        account.setmType(mType);
        account.setmNid(mNid);
        account.setmBid(mBid);
        account.setmGuid(mGuid);
        accountList.add(account);
    }
}
